import ReactMarkdown from 'react-markdown'
import 'katex/dist/katex.min.css'
import SyntaxHighlighter from 'react-syntax-highlighter'
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
import RehypeKatex from 'rehype-katex'
import rehypeRaw from 'rehype-raw'
import RemarkBreaks from 'remark-breaks'
import RemarkGfm from 'remark-gfm'
import RemarkMath from 'remark-math'
import { filterTags } from './render-widgets/utils'
import CustomMessageRender from './CustomMessageRender'
import { RenderWidget } from './render-widgets'
export function Markdown(props: { content: string | { text: string } }) {
  if (typeof props.content === 'object' && props.content) {
    return (
      <CustomMessageRender data={props.content}/>
    )
  }
  const content = props.content
  return (
    <div className="markdown-body">
      <ReactMarkdown
        remarkPlugins={[RemarkMath, RemarkGfm, RemarkBreaks]}
        rehypePlugins={[
          RehypeKatex,
          rehypeRaw,
        ]}
        skipHtml={false}
        components={{
          div: ({
            children,
            node,
          }) => {
            const getPropKey = (key: string) => {
              return (node.properties && Object.hasOwn(node.properties, key)) ? key.replace('data', '').toLowerCase() : ''
            }
            const ppk = getPropKey('dataCxr')
            const rpk = getPropKey('dataCxp')
            const extProps = [ppk, rpk].filter(Boolean).reduce<Record<string, any>>((acc, c) => ({
              ...acc,
              'data-chat-role': c,
            }), {})
            return (
              <div {...extProps} className="md-html-node">{children}</div>
            )
          },
          span: ({
            children,
            node,
          }) => {
            const role = node.properties?.dataRole
            if (!role)
              return children
            return (
              <RenderWidget role={String(role)} children={children}/>
            )
          },
          li: ({
            children,
          }) => {
            if (!Array.isArray(children))
              return <li>{children}</li>
            return (
              <li>
                {
                  (children || []).map((v) => {
                    if (typeof v === 'string')
                      return filterTags(v)

                    return v
                  })
                }
              </li>
            )
          },
          code({
            node,
            inline,
            className,
            children,
            ...props
          }) {
            const match = /language-(\w+)/.exec(className || '')
            return (!inline && match)
              ? (
                <SyntaxHighlighter
                  {...props}
                  children={String(children).replace(/\n$/, '')}
                  style={atelierHeathLight}
                  language={match[1]}
                  showLineNumbers
                  PreTag="div"
                />
              )
              : (
                <code {...props} className={className}>
                  {children}
                </code>
              )
          },
        }}
        linkTarget={'_blank'}
      >
        {content}
      </ReactMarkdown>
    </div>
  )
}
